package com.zzw.config;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.concurrent.TimeUnit;

/**
 * Redis会话管理器
 * 实现Shiro会话的Redis存储
 */
@Component
public class RedisSessionManager extends AbstractSessionDAO {

    // Redis中存储Session的键前缀
    private static final String SESSION_PREFIX = "shiro:session:";
    
    // 会话超时时间（秒）
    private static final int SESSION_TIMEOUT = 1800;

    @Autowired
    @Qualifier("shiroSessionRedisTemplate")
    private RedisTemplate<String, Session> redisTemplate;

    /**
     * 创建会话
     */
    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = generateSessionId(session);
        assignSessionId(session, sessionId);
        saveSession(session);
        return sessionId;
    }

    /**
     * 读取会话
     */
    @Override
    protected Session doReadSession(Serializable sessionId) {
        if (sessionId == null) {
            return null;
        }
        return getSession(sessionId);
    }

    /**
     * 更新会话
     */
    @Override
    public void update(Session session) throws UnknownSessionException {
        saveSession(session);
    }

    /**
     * 删除会话
     */
    @Override
    public void delete(Session session) {
        if (session == null || session.getId() == null) {
            return;
        }
        String key = getSessionKey(session.getId().toString());
        redisTemplate.delete(key);
    }

    /**
     * 获取活动会话
     */
    @Override
    public Collection<Session> getActiveSessions() {
        // 此方法实现可能较复杂，需要查询Redis中所有匹配前缀的键
        // 简化实现，返回空集合，通常这个方法不会被频繁调用
        return new HashSet<>();
    }

    /**
     * 保存会话
     */
    private void saveSession(Session session) {
        if (session == null || session.getId() == null) {
            return;
        }
        
        String key = getSessionKey(session.getId().toString());
        // 使用会话超时时间设置Redis的过期时间
        long timeout = session.getTimeout() / 1000;
        redisTemplate.opsForValue().set(key, session, timeout > 0 ? timeout : SESSION_TIMEOUT, TimeUnit.SECONDS);
    }

    /**
     * 获取会话
     */
    private Session getSession(Serializable sessionId) {
        String key = getSessionKey(sessionId.toString());
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 获取会话Key
     */
    private String getSessionKey(String sessionId) {
        return SESSION_PREFIX + sessionId;
    }
} 